package top.itaso.lib.common;

import android.text.format.DateUtils;

import androidx.annotation.StringDef;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @Description: 时间转换工具类
 * @Author itsdf07
 * @E-Mail 923255742@qq.com
 * @Gitee https://gitee.com/itsdf07
 * @Date 2021/11/22
 */
public class DateTimeUtils {
    private static final String TAG = "DateTimeUtils";
    /**
     * 测试时间戳
     */
    public static final long TEST_TIME = 1628401609000L;

    public static final String FORMAT_YYYY = "yyyy";
    public static final String FORMAT_YYYYMMDD = "yyyy-MM-dd";
    public static final String FORMAT_YYYYMMDD1 = "yyyy/MM/dd";
    public static final String FORMAT_YYYYMMDD2 = "yyyy年MM月dd日";
    public static final String FORMAT_YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss";
    public static final String FORMAT_YYYYMMDDHHMMSS1 = "yyyy/MM/dd HH:mm:ss";
    public static final String FORMAT_YYYYMMDDHHMMSS2 = "yyyy年MM月dd日 HH:mm";
    public static final String FORMAT_YYYYMMDDHHMMSS3 = "yyyyMMddHHmmss";
    public static final String FORMAT_MMDDHHMM = "MM月dd日 HH:mm";

    @StringDef(value = {
            FORMAT_YYYY,
            FORMAT_YYYYMMDD,
            FORMAT_YYYYMMDD1,
            FORMAT_YYYYMMDD2,
            FORMAT_YYYYMMDDHHMMSS,
            FORMAT_YYYYMMDDHHMMSS1,
            FORMAT_YYYYMMDDHHMMSS2,
            FORMAT_YYYYMMDDHHMMSS3,
            FORMAT_MMDDHHMM
    })
    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.SOURCE)
    public @interface DateStyle {
        String value();
    }

    public enum EDateStyle {
        YYYY("yyyy"),
        YYYYMMDD("yyyy-MM-dd"),
        YYYYMMDD1("yyyy/MM/dd"),
        YYYYMMDD2("yyyy年MM月dd日"),
        YYYYMMDDHHMMSS("yyyy-MM-dd HH:mm:ss"),
        YYYYMMDDHHMMSS1("yyyy/MM/dd HH:mm:ss"),
        YYYYMMDDHHMMSS2("yyyy年MM月dd日 HH:mm"),
        YYYYMMDDHHMMSS3("yyyyMMddHHmmss"),
        MMDDHHMM("MM月dd日 HH:mm");

        private String dateStyle;

        EDateStyle(String dateStyle) {
            this.dateStyle = dateStyle;
        }

        public String getDateStyle() {
            return dateStyle;
        }

        public static EDateStyle getByType(String type) {
            for (EDateStyle constants : values()) {
                if (constants.getDateStyle().equalsIgnoreCase(type)) {
                    return constants;
                }
            }
            return YYYYMMDDHHMMSS;
        }
    }

    /**
     * 判断是否为今天(效率比较高)
     *
     * @param millis 目标时间戳：毫秒
     * @return true-今天，false-不是今天
     */
    public static boolean isToday(long millis) {
        Calendar calendar = Calendar.getInstance();
        Date date = new Date(millis);
        calendar.setTime(date);//设置求解日期

        Calendar todayCal = Calendar.getInstance();
        Date todayTime = new Date(System.currentTimeMillis());
        todayCal.setTime(todayTime);//设置当天日期

        //年份与日均相同，则为同一天：今天
        if (calendar.get(Calendar.YEAR) == (todayCal.get(Calendar.YEAR))) {
            int diffDay = calendar.get(Calendar.DAY_OF_YEAR) - todayCal.get(Calendar.DAY_OF_YEAR);
            if (diffDay == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否为昨天(效率比较高)
     *
     * @param millis 目标时间戳：毫秒
     * @return true今天 false不是
     */
    public static boolean isYesterday(long millis) {
        Calendar yesterdayCal = Calendar.getInstance();
        Date yesterdayDate = new Date(millis);
        yesterdayCal.setTime(yesterdayDate);

        Calendar todayCal = Calendar.getInstance();
        Date todayDate = new Date(System.currentTimeMillis());
        todayCal.setTime(todayDate);

        if ((yesterdayCal.get(Calendar.YEAR) - todayCal.get(Calendar.YEAR)) == 0) {//同一年
            int diffDay = todayCal.get(Calendar.DAY_OF_YEAR) - yesterdayCal.get(Calendar.DAY_OF_YEAR);
            if (diffDay == 1) {
                return true;
            }
        }
        if ((todayCal.get(Calendar.YEAR) - yesterdayCal.get(Calendar.YEAR)) == 1) {//跨了一年
            int diffDay = yesterdayCal.getActualMaximum(Calendar.DAY_OF_YEAR) + todayCal.get(Calendar.DAY_OF_YEAR) - yesterdayCal.get(Calendar.DAY_OF_YEAR);
            if (diffDay == 1) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否为明天(效率比较高)
     *
     * @param millis 目标时间戳：毫秒
     * @return true今天 false不是
     */
    public static boolean isTomorrow(long millis) {
        Calendar tomorrowCal = Calendar.getInstance();
        Date tomorrowDate = new Date(millis);
        tomorrowCal.setTime(tomorrowDate);

        Calendar todayCal = Calendar.getInstance();
        Date todayDate = new Date(System.currentTimeMillis());
        todayCal.setTime(todayDate);

        if ((tomorrowCal.get(Calendar.YEAR) - todayCal.get(Calendar.YEAR)) == 0) {//同一年
            int diffDay = tomorrowCal.get(Calendar.DAY_OF_YEAR) - todayCal.get(Calendar.DAY_OF_YEAR);
            if (diffDay == 1) {
                return true;
            }
        }
        if ((tomorrowCal.get(Calendar.YEAR) - todayCal.get(Calendar.YEAR)) == 1) {//跨了一年
            int diffDay = todayCal.getActualMaximum(Calendar.DAY_OF_YEAR) + tomorrowCal.get(Calendar.DAY_OF_YEAR) - todayCal.get(Calendar.DAY_OF_YEAR);
            if (diffDay == 1) {
                return true;
            }
        }
        return false;
    }

    /**
     * 计算两个日期相隔的天数.
     *
     * @param startMillis 计算的起点时间戳：毫秒
     * @param endMillis   计算的截止时间戳：毫秒
     * @return 返回两个日期相隔的天数, 如果是同一天返回 0.
     */
    public static int daysBetween(long startMillis, long endMillis) {
        Calendar startTimeCal = Calendar.getInstance();
        startTimeCal.setTime(new Date(startMillis));

        Calendar endTimeCal = Calendar.getInstance();
        endTimeCal.setTime(new Date(endMillis));

        if (startTimeCal.after(endTimeCal)) {//矫正日期，确保参数前后日期颠倒时不会计算异常
            Calendar swap = startTimeCal;
            startTimeCal = endTimeCal;
            endTimeCal = swap;
        }

        int days = endTimeCal.get(Calendar.DAY_OF_YEAR) - startTimeCal.get(Calendar.DAY_OF_YEAR);
//        int days = 0 - startTimeCal.get(Calendar.DAY_OF_YEAR) + endTimeCal.get(Calendar.DAY_OF_YEAR);
        int year2EndMills = endTimeCal.get(Calendar.YEAR);//截止时间的年份
        if (startTimeCal.get(Calendar.YEAR) != year2EndMills) {
            startTimeCal = (Calendar) startTimeCal.clone();
            do {
                days += startTimeCal.getActualMaximum(Calendar.DAY_OF_YEAR);
                startTimeCal.add(Calendar.YEAR, 1);//表示对年进行加一年的操作
            } while (startTimeCal.get(Calendar.YEAR) != year2EndMills);
        }
        return days;
    }


    /**
     * 时间过去时的时差显示（通常用于文案显示）
     *
     * @param millis 目标时间戳：毫秒
     * @return 时间戳转成提示性日期格式（刚刚、x分钟前、小于24小时的 xx:xx、x小时前、MM月dd日 HH:mm、yyyy年MM月dd日 HH:mm……)
     */
    public static String formatDateTimeStyleTdoa(long millis) {//Tdoa:到达时间差(Time Difference Of Arrival)
        long currentTimeMillis = System.currentTimeMillis();
        long tdoa = currentTimeMillis - millis;//时间差
        if (tdoa <= 0) {
            return "Future time";
        }
        if (tdoa < 1000 * 60 * 5) {//小于5分钟---刚刚
            return "刚刚";
        }
        if (tdoa < 1000 * 60 * 60) {//小于1小时--- 7分钟前
            return DateUtils.getRelativeTimeSpanString(millis).toString();
        }

        if (tdoa < 1000 * 60 * 60 * 24) {//小于24小时--- 3小时前
            int hour = (int) (tdoa / (1000 * 60 * 60));
            return String.format("%d小时前", hour);
        }

        Calendar currentCal = Calendar.getInstance();
        currentCal.setTime(new Date(currentTimeMillis));
        int currentYear = currentCal.get(Calendar.YEAR);

        Calendar millisCal = Calendar.getInstance();
        millisCal.setTime(new Date(millis));
        int millisYear = millisCal.get(Calendar.YEAR);

        if (currentYear == millisYear) {//与当前同一年：03月29日 12:33
            String now = formatDateTimeStyle(millis, EDateStyle.MMDDHHMM);
            return now;
        }
        return formatDateTimeStyle(millis, EDateStyle.YYYYMMDDHHMMSS2);//跨年过一年：2022年03月29日 12:33
    }


    /**
     * 根据时间毫秒数格式化时间
     *
     * @param millis 目标时间戳：毫秒
     * @return 格式化时间 YYYYMMDDHHMMSS
     */
    public static String formatDateTimeStyle(long millis) {
        return formatDateTimeStyle(millis, FORMAT_YYYYMMDDHHMMSS);
    }

    /**
     * 根据时间毫秒数格式化时间
     *
     * @param millis 目标时间戳：毫秒
     * @param style  格式
     * @return 格式化时间
     * @see EDateStyle
     */
    public static String formatDateTimeStyle(long millis, EDateStyle style) {
        Date date = new Date(millis);
        String strTime;
        SimpleDateFormat df = new SimpleDateFormat(style.dateStyle);
        strTime = df.format(date);
        return strTime;
    }

    /**
     * 根据时间毫秒数格式化时间
     *
     * @param millis 目标时间戳：毫秒
     * @param style  格式
     * @return 格式化时间
     */
    public static String formatDateTimeStyle(long millis, @DateStyle(FORMAT_YYYY) String style) {
        Date date = new Date(millis);
        String strTime;
        SimpleDateFormat df = new SimpleDateFormat(style);
        strTime = df.format(date);
        return strTime;
    }

}
